package basic.socket;
import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.Date;
import java.util.Iterator;

/**
 * @author bingo
 * @Description      基于NIO的通信，但还是阻塞式的
 * @Date 2018/7/30
 */
public class SocketChannelDemo {

    @Test
    public void client(){

        SocketChannel socketChannel =null;
        FileChannel fileChannel = null;
        try {
            socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",8888));
            fileChannel = FileChannel.open(Paths.get("demo/1.png"),StandardOpenOption.READ);
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (fileChannel.read(buffer)!=-1){
                buffer.flip();
                socketChannel.write(buffer);
                buffer.clear();
            }

            System.out.println("发送完毕~~~~~~~~~~~~~~~");
            socketChannel.shutdownOutput();
            int len  = 0;
            while ((len =socketChannel.read(buffer))!=-1){
                buffer.flip();
                System.out.println("服务端:"+new String(buffer.array(),0,len));
                buffer.clear();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                socketChannel.close();
                fileChannel.close();
            } catch (IOException e) {
                e.printStackTrace();
            }

        }

    }

    @Test
    public void Server(){
     ServerSocketChannel serverSocketChannel =null;
     FileChannel fileChannel =null;
     SocketChannel socketChannel =null;
     try {
            serverSocketChannel = ServerSocketChannel.open();
            serverSocketChannel.bind(new InetSocketAddress("127.0.0.1",8888));
            fileChannel = FileChannel.open(Paths.get("demo/2.png"), StandardOpenOption.WRITE,StandardOpenOption.CREATE);
            socketChannel = serverSocketChannel.accept();
            ByteBuffer buffer = ByteBuffer.allocate(1024);
            while (socketChannel.read(buffer)!=-1){
                buffer.flip();
                fileChannel.write(buffer);
                buffer.clear();
            }
             System.out.println("接受完毕~~~~~~~~~~~~");
            buffer.put("文件上传完毕!".getBytes());
            buffer.flip();
            socketChannel.write(buffer);

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
          try {
              if(serverSocketChannel !=null){
                  serverSocketChannel.close();
              }
              if(fileChannel!=null){
                  fileChannel.close();
              }
              if(socketChannel!=null){
                  socketChannel.close();
              }

          } catch (IOException e) {
              e.printStackTrace();
          }

        }
    }


    @Test
    public void  client2(){

        try {

            SocketChannel socketChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1",9898));
            //切换位非阻塞模式
            socketChannel.configureBlocking(false);

            ByteBuffer byteBuffer = ByteBuffer.allocate(1024);

            byteBuffer.put(new Date().toString().getBytes());

            byteBuffer.flip();

            socketChannel.write(byteBuffer);

            byteBuffer.clear();


            socketChannel.close();
            } catch (IOException e) {
            e.printStackTrace();
        }


    }
    @Test
  public void server2() throws InterruptedException {

      try {
          ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

          serverSocketChannel.configureBlocking(false);

          serverSocketChannel.bind(new InetSocketAddress(9898));

          Selector selector = Selector.open();

          serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

          while(selector.select() > 0){

              Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();

              while(iterator.hasNext()){

                 SelectionKey selectionKey = iterator.next();

                 if(selectionKey.isAcceptable()){
                     System.out.println("xxxxxxxxxxxx");

                     SocketChannel socketChannel = serverSocketChannel.accept();

                     socketChannel.configureBlocking(false);

                     socketChannel.register(selector,SelectionKey.OP_READ);



                 }else if(selectionKey.isReadable()){
                     Thread.sleep(150);
                     System.out.println("开始读取~~~~~~~");
                     SocketChannel socketChannel = (SocketChannel) selectionKey.channel();
                     ByteBuffer buffer = ByteBuffer.allocate(1024);
                     int len =0;
                     while((len=socketChannel.read(buffer))>0){
                         buffer.flip();
                         System.out.println(new String(buffer.array(),0,len));
                         buffer.clear();
                     }
                 }
                  iterator.remove();
              }

          }


      } catch (IOException e) {
          e.printStackTrace();
      }

  }

  @Test
  public  void testWhile(){

        while (true){
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("hello");
        }
  }
  /**
   *    put();
   *    flip();
   *    get();
   *    rewind();
   *    clear();
   *    * */
  @Test
  public void testBuffer(){
      ByteBuffer bys = ByteBuffer.allocate(10);
      System.out.println("起始状态~~~~~~~~~~~~~~~~~~~··");
      System.out.println(bys.position());
      System.out.println(bys.limit());
      System.out.println(bys.capacity());
      System.out.println("put~~~~~~~~~~~~~~·~~~~~~·");
       String msg = "abcde";
       bys.put(msg.getBytes());
       System.out.println(bys.position());
       System.out.println(bys.limit());
       System.out.println(bys.capacity());
       System.out.println("flip~~~~~~~~~~~~~~~~~~~~~");
       bys.flip();
       System.out.println(bys.position());
       System.out.println(bys.limit());
       System.out.println(bys.capacity());
       System.out.println("get~~~~~~~~~~~~~~~~~~~~~");
       byte[] readByte = new byte[bys.limit()];
       bys.get(readByte,0,readByte.length);
       System.out.println(bys.position());
       System.out.println(bys.limit());
       System.out.println(bys.capacity());
       System.out.println("rewind~~~~~~~~~~~~~~~~~~~~~");
       bys.rewind();
       System.out.println(bys.position());
       System.out.println(bys.limit());
       System.out.println(bys.capacity());
       System.out.println(new String(bys.array()));
       System.out.println("clear~~~~~~~~~~~~~~~~~~~~~");
       bys.clear();
       System.out.println(bys.position());
       System.out.println(bys.limit());
       System.out.println(bys.capacity());
       System.out.println(new String(bys.array()));


  }

  @Test
  public  void testMark(){
      String msg = "abcde";
      ByteBuffer bys = ByteBuffer.allocate(1024);
      bys.put(msg.getBytes());

      bys.flip();
      byte[] b1 = new byte[bys.limit()];
      bys.get(b1,0,2);
      System.out.println(new String(b1));

      bys.mark();
      System.out.println(bys.position());
      bys.get(b1,2,2);
      System.out.println(new String(b1));
      System.out.println(bys.position());
      //恢复到markd的位置
      bys.reset();
      System.out.println(bys.position());
  }




}
